package com.sofa.common.config;

import com.sofa.common.constants.MqConstants;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Rabbitmq死信队列配置
 */
@Configuration
public class RabbitMqDeadLetterConfig {

    public static final String LOG_QUEUE = MqConstants.Queue.SOFA_LOG_QUEUE;
    public static final String LOG_DLX_EXCHANGE = "sofa.log.dlx";
    public static final String LOG_DLX_ROUTING_KEY = "sofa.log.dead";
    public static final String LOG_DEAD_QUEUE = "sofa.log.queue.dead";


    /**
     * 主业务队列，带死信转发参数
     */
    @Bean
    public Queue sofaLogQueue() {
        return QueueBuilder.durable(LOG_QUEUE)
                .withArgument("x-dead-letter-exchange", LOG_DLX_EXCHANGE)
                .withArgument("x-dead-letter-routing-key", LOG_DLX_ROUTING_KEY)
                .build();
    }

    /**
     * 死信交换机
     */
    @Bean
    public DirectExchange sofaLogDlxExchange() {
        return new DirectExchange(LOG_DLX_EXCHANGE);
    }

    /**
     * 死信队列
     */
    @Bean
    public Queue sofaLogDeadQueue() {
        return QueueBuilder.durable(LOG_DEAD_QUEUE).build();
    }

    /**
     * 将死信队列绑定到死信交换机上
     */
    @Bean
    public Binding sofaLogDeadBinding() {
        return BindingBuilder.bind(sofaLogDeadQueue())
                .to(sofaLogDlxExchange())
                .with(LOG_DLX_ROUTING_KEY);
    }

    /**
     * 将交换机绑定到死信队列
     * 一旦手动声明了 Queue 和 Exchange，Binding 也必须手动声明,不然就无法将交换机绑定到队列
     * 因为手动声明后,SpringBoot 就不会自动创建 Queue 和 Exchange了
     * @return
     */
    @Bean
    public Binding sofaLogBinding() {
        return BindingBuilder
                .bind(sofaLogQueue())
                .to(new TopicExchange(MqConstants.Exchange.SOFA_LOG_EXCHANGE))
                .with(MqConstants.RoutingKey.SOFA_LOG_OPERATION);
    }

}
